import {
  Component,
  OnInit,
  Input,
  ViewChild,
  ElementRef,
  AfterViewInit,
  Output,
  EventEmitter
} from '@angular/core';

import {DataTablesComponentConfig, ColumnDef} from './data-tables-component-config.class';
import {defaultConfig} from 'app/theme/datatables-config-default';
import 'datatables';

@Component({
  selector: 'data-tables',
  templateUrl: 'data-tables.component.html',
  styleUrls: ['data-tables.component.scss'],
})
export class DataTablesComponent implements OnInit, AfterViewInit {
  @Input() config: DataTablesComponentConfig;
  @Input() searchParams: any;
  @ViewChild('dataTable') table: ElementRef;
  @Output() onSelect: EventEmitter<any> = new EventEmitter();
  @Output() onError: EventEmitter<any> = new EventEmitter();
  dataTable: any;
  private isAllSelected: boolean = false;

  constructor() {
  }

  ngOnInit() {
  }

  ngAfterViewInit() {
    let config = this.assembleConfig();

    jQuery.fn.dataTable.ext.errMode = 'none';
    this.dataTable = jQuery(this.table.nativeElement).on('error.dt', (e, settings, techNote, message) => {
      this.emitOnErrorEvent(e);
    }).DataTable(config);

    // 控制全选 checkbox
    if (this.config.selectable === true) {
      this.enableMultiSelection();
    } else if (this.config.selectable === 'single') {
      this.enableSingleSelection();
    }
  }

  enableSingleSelection() {
    let self = this;
    let $tbody = jQuery(self.table.nativeElement).find('tbody');
    $tbody.on('click', 'tr', function (event) {

      if (!jQuery(event.target).is(':checkbox')) {
        // 如果不是checkbox 需要清除其它行checkbox的选中状态，再选中本行的checkbox
        jQuery('tbody .row-selector input[type="checkbox"]').each(function () {
          jQuery(this).prop('checked', false);
        });

        let checkbox = jQuery(this).find('.row-selector input[type="checkbox"]');
        checkbox.prop('checked', !checkbox.prop('checked'));
      } else {
        // 如果是checkbox 只需要清除其它行checkbox的选中状态
        jQuery('tbody .row-selector input[type="checkbox"]').each(function () {
          jQuery(this).prop('checked', event.target === this);
        });
      }
      let $row = jQuery(this);
      let unselectCurrentRow = $row.hasClass('selected');

      $tbody.find('tr').removeClass('selected');

      if (!unselectCurrentRow) {
        jQuery(this).addClass('selected');
      } else {
        // 清除本行checkbox的选中状态
        jQuery(this).find('.row-selector input[type="checkbox"]').prop('checked', false);
      }

      self.emitOnSelectEvent();
    });
  }

  enableMultiSelection() {
    let self = this;

    jQuery('tbody .row-selector input[type="checkbox"]').click(function () {
      self.checkSelectStatus(jQuery(this));
    });

    jQuery(self.table.nativeElement).find('tbody').on('click', 'tr', function (event) {
      // 如果直接点击的checkbox，那么只用为 tr 添加 ‘selected’类，如果点击的是其他dom元素
      // 那么就要toggle checkbox
      if (!jQuery(event.target).is(':checkbox')) {
        let checkbox = jQuery(this).find('.row-selector input[type="checkbox"]');
        checkbox.prop('checked', !checkbox.prop('checked'));

        self.checkSelectStatus(checkbox);
      }
      jQuery(this).toggleClass('selected');
      self.emitOnSelectEvent();
    });
  }

  draw(paging?: boolean) {
    this.dataTable.draw(paging);
  }

  emitOnSelectEvent() {
    this.onSelect.emit(this.dataTable.rows('.selected').data());
  }

  emitOnErrorEvent(e: any) {
    this.onError.emit(e);
  }

  /**
   * 检查每行的选中状态
   */
  checkSelectStatus($checkbox: any) {
    if ($checkbox.prop('checked') && !this.isAllSelected) {
      let isAllChecked = true;
      jQuery('tbody .row-selector input[type="checkbox"]').each(function (index) {
        if (!jQuery(this).prop('checked')) {
          isAllChecked = false;
        }
      });
      this.isAllSelected = isAllChecked;
    } else if (!jQuery(this).prop('checked')) {
      this.isAllSelected = false;
    }
    jQuery('#selectAll').prop('checked', this.isAllSelected);
  }


  /**
   * 选择所有行
   */
  selectAll(event: any) {
    let $table = jQuery(this.table.nativeElement);
    if (event.target.checked) {
      this.isAllSelected = true;
      $table.find('tr').addClass('selected');
      $table.find('tbody .row-selector input[type="checkbox"]').prop('checked', true);
    } else {
      this.isAllSelected = false;
      $table.find('tr').removeClass('selected');
      $table.find('tbody .row-selector input[type="checkbox"]').prop('checked', false);
    }
    this.emitOnSelectEvent();
  }

  /**
   * 拼接 datatables 配置
   */
  assembleConfig() {
    let cols = this.assembleColums();

    let customConfig: any = {
      'ajax': {
        'url': this.config.ajaxUrl
      },
      'columns': cols,
      "order": [[cols.length-3, "desc"]],
  }
    ;

    if (this.searchParams !== null && this.searchParams !== undefined) {
      let props = Object.keys(this.searchParams);
      customConfig.ajax['data'] = (function (d) {
        props.forEach(prop => {
          d[prop] = this.searchParams[prop];
        });
      }).bind(this);
    }

    return Object.assign({}, defaultConfig, customConfig);
  }

  /**
   * 拼接行配置
   */
  assembleColums() {
    let columns: any[] = new Array<any>();

    if (this.config.selectable === true || this.config.selectable === 'single') {
      columns.push(
        {
          'class': 'row-selector',
          'data': null,
          'defaultContent': '<input type="checkbox">'
        }
      );
    }

    this.config.columnsDef.forEach(col => {
      columns.push({'data': col.id, 'orderable': col.orderable,});
    });
    return columns;
  }
}

